﻿
using System;
using System.Drawing;
using System.Windows.Forms;

namespace ShapeManager
{
    public class URectangle : DrawObject
    {
        public override int HandleCount => 8;

        #region 构造函数
        public URectangle() : this(0, 0, 1, 1) {}
        public URectangle(int x, int y, int width, int height) : base()
        {
            X = x;
            Y = y;
            Width = width;
            Height = height;
            Description = "ROI";
            Type = ShapeType.Rectangle;
            Initialize();
        }
        public override void Normalize()
        {
            _rectangleF = GetNormalizedRectangle(_rectangleF);
        }
        #endregion

        #region 基础方法
        public override DrawObject Clone()
        {
            URectangle uRectangle = new URectangle();
            uRectangle._rectangleF = this._rectangleF;
            uRectangle.ID = this.ID;
            Clone(uRectangle);
            return uRectangle;
        }
        public override void Draw(Graphics graphics)
        {
            if (!IsInterest)
            {
                Color tempColor = BackColor;
                BackColor = InterestColor;
                DrawRegion(graphics);
                BackColor = tempColor;
            }
            else if (IsInterest&&IsSelected)
            {
                DrawRegion(graphics);
            }
            DrawBorder(graphics);
            DrawCenter(graphics);
            DrawDescription(graphics);
        }
        public override void Move(float deltaX, float deltaY)
        {
            _rectangleF.X += deltaX;
            _rectangleF.Y += deltaY;
        }
        public override void MoveHandleTo(PointF point, int handleNumber)
        {
            float left = Region.Left;
            float top = Region.Top;
            float right = Region.Right;
            float bottom = Region.Bottom;
            switch (handleNumber)
            {
                case 1:
                    left = point.X;
                    top = point.Y;
                    break;
                case 2:
                    top = point.Y;
                    break;
                case 3:
                    right = point.X;
                    top = point.Y;
                    break;
                case 4:
                    right = point.X;
                    break;
                case 5:
                    right = point.X;
                    bottom = point.Y;
                    break;
                case 6:
                    bottom = point.Y;
                    break;
                case 7:
                    left = point.X;
                    bottom = point.Y;
                    break;
                case 8:
                    left = point.X;
                    break;
            }
           
            SetRectangle(left, top, right - left, bottom - top);
        }
        public override PointF GetHandle(int handleNumber)
        {
            RectangleF rectangle = _rectangleF;
            float x, y, xCenter, yCenter;
            xCenter = rectangle.X + rectangle.Width / 2;
            yCenter = rectangle.Y + rectangle.Height / 2;
            x = rectangle.X;
            y = rectangle.Y;
            switch (handleNumber)
            {
                case 1:
                    x = rectangle.X;
                    y = rectangle.Y;
                    break;
                case 2:
                    x = xCenter;
                    y = rectangle.Y;
                    break;
                case 3:
                    x = rectangle.Right;
                    y = rectangle.Y;
                    break;
                case 4:
                    x = rectangle.Right;
                    y = yCenter;
                    break;
                case 5:
                    x = rectangle.Right;
                    y = rectangle.Bottom;
                    break;
                case 6:
                    x = xCenter;
                    y = rectangle.Bottom;
                    break;
                case 7:
                    x = rectangle.X;
                    y = rectangle.Bottom;
                    break;
                case 8:
                    x = rectangle.X;
                    y = yCenter;
                    break;
            }
            return new PointF(x, y);
        }
        public override int HitTest(PointF point)
        {
            if (IsSelected)
            {
                for (int i = 1; i <= HandleCount; i++)
                {
                    if (GetHandleRectangle(i).Contains(point))
                        return i;
                }
            }
            if (PointInObject(point))
                return 0;

            return -1;
        }
        public override bool IntersectsWith(RectangleF rectangle)
        {
            return Region.IntersectsWith(rectangle);
        }
        public override Cursor GetHandleCursor(int handleNumber)
        {
            switch (handleNumber)
            {
                case 1:
                    return Cursors.SizeNWSE;
                case 2:
                    return Cursors.SizeNS;
                case 3:
                    return Cursors.SizeNESW;
                case 4:
                    return Cursors.SizeWE;
                case 5:
                    return Cursors.SizeNWSE;
                case 6:
                    return Cursors.SizeNS;
                case 7:
                    return Cursors.SizeNESW;
                case 8:
                    return Cursors.SizeWE;
                default:
                    return Cursors.Default;
            }
        }
        protected override bool PointInObject(PointF point)
        {
            return Region.Contains(point);
        }
        /// <summary>  设置矩形 </summary>
        protected void SetRectangle(float x, float y, float width, float height)
        {
            _rectangleF.X = x;
            _rectangleF.Y = y;
            _rectangleF.Width = width;
            _rectangleF.Height = height;
        }
        protected void DrawDescription(Graphics graphics)
        {
            using (SolidBrush brush = new SolidBrush(Color.LightGreen))
            {
                Font descriptionFont = new Font("Arial", 9);
                string text = $"{Description}_{ID}(X:{X},Y:{Y})";
                SizeF maxTextSize = graphics.MeasureString(text, descriptionFont);
                float x = X + (Width - maxTextSize.Width) / 2;
                float y = Y + (Height - maxTextSize.Height) / 2 - maxTextSize.Height;
                graphics.DrawString(text, descriptionFont, brush, x, y);
            }
        }
        private void DrawBorder(Graphics graphics)
        {
            // 绘制矩形
            using (Pen pen = new Pen(BackColor, BorderWidth))
            {
                graphics.DrawRectangle(pen, Rectangle.Round(Region));
            }
        }
        private void DrawRegion(Graphics graphics)
        {
            // 填充矩形
            using (SolidBrush brush = new SolidBrush(Color.FromArgb(Alpha, BackColor)))
            {
                graphics.FillRectangle(brush, Region);
            }
        }
        #endregion

        #region 辅助方法
        /// <summary> 获取标准化矩形 </summary>
        public static RectangleF GetNormalizedRectangle(float x1, float y1, float x2, float y2)
        {
            if (x2 < x1)
            {
                float tmp = x2;
                x2 = x1;
                x1 = tmp;
            }
            if (y2 < y1)
            {
                float tmp = y2;
                y2 = y1;
                y1 = tmp;
            }
            return new RectangleF(x1, y1, x2 - x1, y2 - y1);
        }
        /// <summary> 获取标准化矩形 </summary>
        public static RectangleF GetNormalizedRectangle(PointF p1, PointF p2)
        {
            return GetNormalizedRectangle(p1.X, p1.Y, p2.X, p2.Y);
        }
        /// <summary> 获取标准化矩形 </summary>
        public static RectangleF GetNormalizedRectangle(RectangleF r)
        {
            return GetNormalizedRectangle(r.X, r.Y, r.X + r.Width, r.Y + r.Height);
        }
        #endregion

    }
}
